package com.activenetwork.smlite.page.rfp.RfpMaintenanceView;

import java.util.List;

import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.activenetwork.custom.uielement.UIElement;
import com.activenetwork.custom.uielement.decorate.InJson;
import com.activenetwork.schema.model.rfp.RfpSleepingRequirementType;
import com.activenetwork.schema.model.rfp.SleepingRoomInfoType;
import com.activenetwork.smlite.page.rfp.RfpBasicsSubview;
import com.activenetwork.smlite.snippet.RfpDateCalculator;
import com.activenetwork.smlite.snippet.RfpDay;
import com.activenetwork.util.EnvContext;
import com.activenetwork.util.PageLoader;
import com.activenetwork.util.WaitUtil;
import com.google.common.collect.Lists;

public class RfpSleepingRoom extends RfpBasicsSubview {
	private Logger logger = LoggerFactory.getLogger(RfpSleepingRoom.class);
	
	@InJson
	private UIElement additionInformationHeader;
	@InJson
	private UIElement sleepingRoomComment;
	
	/**
	 * Setup Rfp sleeping room preceding days 
	 * @param sleepingRoomData
	 * @param calculator
	 * @return
	 */
	public RfpSleepingRoom setPrecedingSleepingRoom(RfpSleepingRequirementType sleepingRoomData, RfpDateCalculator calculator){
		logger.info("Start to set sleeping room preceding days");
		// XML data
		List<SleepingRoomInfoType> precedingShoulderData = getCategorySleepingRooms(sleepingRoomData, "pre");
		// Date model
		List<RfpDay> precedingDays = calculator.getRfpDays("pre");
		// Warning 
		if(precedingShoulderData.size() != precedingDays.size()){
			logger.warn("Sleepig Room preceding XML node : " + precedingShoulderData.size() + " Calculated preceding day : " + precedingDays.size());
		}
		
		// Set each preceding day sleeping room info
		for(int i=0; i<precedingDays.size(); i++){
			SleepingRoomInfoType sr_data = null;
			try{
				sr_data = precedingShoulderData.get(i);
			}catch(IndexOutOfBoundsException e){
				
			}
			precedingDays.get(i).setSleepingRoom(sr_data);
		}
		
		for(RfpDay day : precedingDays){
			setSleepingRoomDay(day.getDate(), day.getSleepingRoom());
		}
		
		logger.info("Finish setting sleeping room preceding days");
		return this;
	}
	/**
	 * Setup rfp sleeping room origin days
	 * @param sleepingRoomData
	 * @param calculator
	 * @return
	 */
	public RfpSleepingRoom setOriginSleepingRoom(RfpSleepingRequirementType sleepingRoomData, RfpDateCalculator calculator){
		logger.info("Start to set sleeping room origin days");
		// XML data
		List<SleepingRoomInfoType> originData = getCategorySleepingRooms(sleepingRoomData, "origin");
		// Date model
		List<RfpDay> originDays = calculator.getRfpDays("origin");
		// Warning 
		if(originData.size() != originDays.size()){
			logger.warn("Sleepig Room origin XML node : " + originData.size() + " Calculated origin day : " + originDays.size());
		}
		
		// Set each origin day sleeping room info
		for(int i=0; i<originDays.size(); i++){
			SleepingRoomInfoType sr_data = null;
			try{
				sr_data = originData.get(i);
			}catch(IndexOutOfBoundsException e){
				
			}
			originDays.get(i).setSleepingRoom(sr_data);
		}
		
		for(RfpDay day : originDays){
			setSleepingRoomDay(day.getDate(), day.getSleepingRoom());
		}
		
		logger.info("Finish setting sleeping room origin days");
		return this;
	}
	/**
	 *  
	 * @param sleepingRoomData
	 * @param calculator
	 * @return
	 */
	public RfpSleepingRoom setFollowingSleepingRoom(RfpSleepingRequirementType sleepingRoomData, RfpDateCalculator calculator){
		logger.info("Start to set sleeping room following days");
		// XML data
		List<SleepingRoomInfoType> followingShoulderData = getCategorySleepingRooms(sleepingRoomData, "post");
		// Date model
		List<RfpDay> followingDays = calculator.getRfpDays("post");
		// Warning 
		if(followingShoulderData.size() != followingDays.size()){
			logger.warn("Sleepig Room following XML node : " + followingShoulderData.size() + " Calculated following day : " + followingDays.size());
		}
		
		// Set each preceding day sleeping room info
		for(int i=0; i<followingDays.size(); i++){
			SleepingRoomInfoType sr_data = null;
			try{
				sr_data = followingShoulderData.get(i);
			}catch(IndexOutOfBoundsException e){
				
			}
			followingDays.get(i).setSleepingRoom(sr_data);
		}
		
		for(RfpDay day : followingDays){
			setSleepingRoomDay(day.getDate(), day.getSleepingRoom());
		}
		
		logger.info("Finish setting sleeping room following days");
		return this;
	}
	
	/**
	 * Query all the sleeping room data and return a list of
	 * Certain type of sleeping room type, type can be: pre, origin, post
	 * @param sleepingRoom
	 * @param category
	 * @return
	 */
	private List<SleepingRoomInfoType> getCategorySleepingRooms(RfpSleepingRequirementType sleepingRoom, String category){
		List<SleepingRoomInfoType> sleepingRooms = sleepingRoom.getSleepingRoomInfo();
		List<SleepingRoomInfoType> targetList = Lists.newArrayList();
		for(SleepingRoomInfoType sr : sleepingRooms){
			if(sr.getCategory().equals(category)){
				targetList.add(sr);
			}
		}
		return targetList;
	}
	
	/**
	 * Setup one row in the sleeping room table
	 * @param dateStr
	 * @param dateInfo
	 */
	public void setSleepingRoomDay(String dateStr, SleepingRoomInfoType dateInfo){
		if(dateInfo != null){
			By rowBy = By.xpath("//div[@class='autotest-grid-RfpSleepingRoomsSubview-rfpsleepingroomsgrid']//tbody[1]" +
					"//tr[descendant::div[text()='" + dateStr + "']]");
			// set singles
			setRoom(rowBy, 3, String.valueOf(dateInfo.getSingles()));
			// set doubles
			setRoom(rowBy, 4, String.valueOf(dateInfo.getDoubles()));
			// set doubles/doubles
			setRoom(rowBy, 5, String.valueOf(dateInfo.getDoubleDouble()));
			// set suites
			setRoom(rowBy, 6, String.valueOf(dateInfo.getSuites()));
			// set staff
			setRoom(rowBy, 7, String.valueOf(dateInfo.getStaff()));
		}else{
			logger.info(dateStr + " has no sleeping room info defined");
		}
	}
	/**
	 * Setup one cell of one row
	 * @param rowBy
	 * @param tdCount
	 * @param value
	 */
	private void setRoom(By rowBy, int tdCount, String value){
		WebDriver driver = EnvContext.webDriverTL.get();
		WaitUtil waitUtil = new WaitUtil();
		WebElement row = driver.findElement(rowBy);
		row.findElement(By.xpath("./td[" + tdCount + "]//div[contains(@class, 'nexus-numberfield')]")).click();
		waitUtil.wait(500);
		WebElement roomInput = driver.findElement(rowBy).findElement(By.xpath("./td[" + tdCount + "]//input"));
		roomInput.clear();
		roomInput.sendKeys(value, Keys.ENTER);
	}
	/**
	 * Show additional information
	 * @return
	 */
	public RfpSleepingRoom showAdditionalInformation(){
		if(getCommentDisplayStatus().contains("hide")){
			additionInformationHeader.click();
			return PageLoader.load(RfpSleepingRoom.class);
		}else{
			return this;
		}
	}
	/**
	 * Hide additional information
	 * @return
	 */
	public RfpSleepingRoom hideAdditionalInformation(){
		if(!getCommentDisplayStatus().contains("hide")){
			additionInformationHeader.click();
			return PageLoader.load(RfpSleepingRoom.class);
		}else{
			return this;
		}
	}
	
	private String getCommentDisplayStatus(){
		WebDriver driver = EnvContext.webDriverTL.get();
		By statusBy = By.cssSelector(".autotest-collapsibleSection-RfpSleepingRoomsSubview-sradditioninfosection .nexus-section-body");
		WebElement div = driver.findElement(statusBy);
		return div.getAttribute("class").trim();
	}
	
	/**
	 * Setup the additional information comment
	 * @param comment
	 * @return
	 */
	public RfpSleepingRoom setComment(String comment){
		sleepingRoomComment.clear();
		sleepingRoomComment.sendKeys(comment);
		return this;
	}

	

	
	
}

